#ifndef DATABASE_H
#define DATABASE_H

#include <QString>
#include <QVariantMap>
#include <QVector>
#include <QSqlDatabase>
#include <QSqlRecord>
#include <QSqlQuery>

class Column {
  public:
    enum Type {Text=0,Real=1,Integer=2};
    const static QString TypeName[3];
    const static QVariant::Type QVariantType[3];
    Column(QString name=QString(),Type=Text);
    ~Column()=default;
    const QString &getTypeName();
    QString name;
    Type type;
};

class Row {
  public:
    Row()=default;
    Row(const QSqlRecord &record);
    ~Row()=default;
    QVariant &operator[](int i);
    QVariantList values;
    void load(const QSqlRecord &record);
    void save();
    int size();
};

class Table {
  public:
    Table(QString name=QString(),QString key=QString());
    ~Table()=default;
	void setKey(int keyId);
	Column &addColumn(Column &&column);
    Column &getColumn(QString columnName);
	Row &addId(QString id);
    Row &addRow(Row &&row);
    Row &getRow(QString id);
    void removeRow(QString id);
    void clearRows();
    Table &clone(QString newName=QString());
    QString name;
	int keyId;
    QVector<Column> columns;
    QStringList columnNames;
    QMap<QString,int> columnId;
    QVector<Row> rows;
	QMap<QString,int> rowId;
};

class Database {
  public:
    Database();
    ~Database()=default;
    Table &addTable(Table &&table);
    Table &getTable(QString tableName);
    void removeTable(QString tableName);
    void clearTables();
    QString name;
    QVector<Table> tables;
    QMap<QString,int> tableId;
};

class Driver {
  public:
    Driver()=default;
    virtual ~Driver()=default;
    virtual void open()=0;
    virtual void close()=0;
    virtual void setDatabase(QString name);
    virtual void loadStructure(Database &database)=0;
    virtual void loadDatabase(Database &database);
    virtual void saveDatabase(Database &database);
    virtual void loadTable(Table &table);
    virtual void saveTable(Table &table);
    QString databaseName;
    QSqlDatabase connection;
};

class DriverSqlite:public Driver {
  public:
    DriverSqlite()=default;
    ~DriverSqlite()=default;
    virtual void open();
    virtual void close();
    virtual void loadStructure(Database &database);
};

#endif // DATABASE_H
